﻿Imports System.IO
Imports System.Text.RegularExpressions
Imports System.Collections
Imports Microsoft.VisualBasic.Strings
Imports System.Text
Imports System.Xml
Imports System.Threading
Imports System.IO.IsolatedStorage
Imports System.Xml.Linq
Imports System.Net.NetworkInformation
Imports ICSharpCode.SharpZipLib.Zip
Imports GalgameParser

Public Class Helper
    Public Const DefaultTimeout As Integer = 2 * 60 * 1000
    Public Const PATTERN_CMCMOBILENUM As String = "^1(3[4-9]|5[012789]|8[78])\d{8}$"
    Public Const PATTERN_CTCMOBILENUM As String = "^18[09]\d{8}$"
    Public Const PATTERN_CUTMOBILENUM As String = "^1(3[0-2]|5[56]|8[56])\d{8}$"
    Public Const PATTERN_CDMAMOBILENUM As String = "^1[35]3\d{8}$"

    Public PATTERN_ALL() As String = New String() {PATTERN_CMCMOBILENUM, PATTERN_CTCMOBILENUM, PATTERN_CUTMOBILENUM, PATTERN_CDMAMOBILENUM}

    Public Shared Function BytesToString(ByVal data() As Byte) As String
        Return BitConverter.ToString(data)
    End Function

    Public Shared Function StringToBytes(ByVal data As String) As Byte()
        Dim elements() As String = data.Split("-")
        Dim lst As New List(Of Byte)
        For Each item In elements
            Dim value As Byte = 0
            For i As Integer = 0 To item.Length - 1
                Dim v As Integer = 0
                Dim a As Byte = AscW(item.Chars(i))
                If a >= AscW("0") And a <= AscW("9") Then
                    v = a - AscW("0")
                Else
                    v = a - AscW("A") + 10
                End If
                value += v * Math.Pow(16, item.Length - i - 1)
            Next i
            lst.Add(value)
        Next item
        Return lst.ToArray()
    End Function

    Public Shared Function Serialize(Of T)(ByRef obj As T) As IO.MemoryStream
        Dim ms As New IO.MemoryStream
        Dim xs As New Xml.Serialization.XmlSerializer(GetType(T))
        xs.Serialize(ms, obj)
        ms.Close()
        Return ms
    End Function

    Public Shared Function Deserialize(Of T)(ByVal ms As IO.Stream) As T
        Dim xs As New Xml.Serialization.XmlSerializer(GetType(T))
        Return xs.Deserialize(ms)
    End Function

    Public Shared Function MatchString(ByVal str1 As String, ByVal str2 As String) As Integer
        Dim ret As Integer = 0
        Dim k As Integer = (New Integer() {str1.Length, str2.Length}).Min()
        If k - 1 >= 0 Then
            For i = 0 To k - 1
                If str1(i) = str2(i) Then
                    ret += 1
                Else
                    Exit For
                End If
            Next i
            Return ret
        Else
            Return 0
        End If
    End Function

    Public Shared Function DeleteSpace(ByVal s As String) As String
        s = s.Trim().Replace(" ", "")
        Return s
    End Function

    Public Shared Function IsChinese(ByVal ch As Char) As Boolean
        Dim pattern As String = "[\u4e00-\u9fa5]"
        Dim rg As Regex = New Regex(pattern)
        Dim mh As Match = rg.Match(ch)
        Return mh.Success
    End Function

    Public Shared Function EscapeChinese(ByVal s As String) As String
        Dim ret As String = ""
        For Each c As Char In s
            If IsChinese(c) = False Then
                ret += c
            End If
        Next c
        Return ret
    End Function

    Public Shared Function FindStringInArray(ByVal term As String, ByRef db() As String) As Integer
        Dim m As Integer = 0
        Dim p As Integer = 0
        For i As Integer = 0 To db.Length - 1
            Dim v As Integer = MatchString(term, db(i))
            If v > m Then
                m = v
                p = i
            End If
        Next i
        Return p
    End Function

    Public Shared Function Left(ByVal s As String, ByVal length As Integer) As String
        Try
            If length > s.Length Then Return s
            Return s.Substring(0, length)
        Catch ex As Exception
            Return ""
        End Try
    End Function

    Public Shared Function Right(ByVal s As String, ByVal length As Integer) As String
        Try
            If length > s.Length Then Return s
            Return s.Substring(s.Length - length, length)
        Catch ex As Exception
            Return ""
        End Try
    End Function

    Public Shared Function GetLeft(ByVal s As String, ByVal part As String) As String
        Try
            Dim inx = s.IndexOf(part)
            Return s.Substring(0, inx)
        Catch ex As Exception
            Return ""
        End Try
    End Function

    Public Shared Function GetRight(ByVal s As String, ByVal part As String) As String
        Try
            Dim inx = s.IndexOf(part)
            Return s.Substring(inx + part.Length)
        Catch ex As Exception
            Return ""
        End Try
    End Function

    Public Shared Function CharToStr(ByVal Chars() As Char) As String
        Return Chars.Aggregate(Function(s1 As String, s2 As String) s1 + s2)
    End Function

    Public Shared Function CharToStr(ByVal Chars() As String) As String
        Return Chars.Aggregate(Function(s1 As String, s2 As String) s1 + s2)
    End Function

    Public Shared Function UnShell(ByVal Path As String) As String
        If Path(0) = ChrW(34) And Right(Path, 1) = ChrW(34) Then
            Return Path.Substring(1, Path.Length - 2)
        Else
            Return Path
        End If
    End Function

    Public Shared Function AddShell(ByVal Path As String) As String
        Return ChrW(34) & Path & ChrW(34)
    End Function

    Public Shared Function ArrayToString(Of T)(ByVal Array() As T, ByVal Filter As String) As String
        If Array.Length = 0 Then
            Return ""
        ElseIf Array.Length = 1 Then
            Return Array(0).ToString()
        End If
        Dim ret As String = Array(0).ToString() & Filter
        For i As ULong = 1 To Array.Length - 2
            ret += Array(i).ToString() & Filter
        Next i
        ret += Array(Array.Length - 1).ToString()
        Return ret
    End Function

    Public Shared Function PathConnect(ByVal path1 As String, ByVal path2 As String) As String
        If IO.Directory.Exists(path1) Then
            Return IO.Path.Combine(path1, path2)
        Else
            Throw New Exception("Path1 is not valid!")
        End If
    End Function

    Public Shared Function FindFirstElementInVisualTree(Of T As DependencyObject)(ByVal parentElement As DependencyObject) As T
        Dim count = VisualTreeHelper.GetChildrenCount(parentElement)
        If count = 0 Then
            Return Nothing
        Else
            For i As Integer = 0 To count - 1
                Dim child = VisualTreeHelper.GetChild(parentElement, i)
                If child IsNot Nothing And (TypeOf child Is T) Then
                    Return CType(child, T)
                Else
                    Dim result = FindFirstElementInVisualTree(Of T)(child)
                    If result IsNot Nothing Then
                        Return result
                    End If
                End If
            Next
            Return Nothing
        End If
    End Function

    Public Shared Function [Try](ByVal act As System.Action) As Boolean
        Try
            Call act()
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Public Shared Function CheckUri(ByVal uri As String) As Boolean
        Dim state As New Tuple(Of AutoResetEvent, Boolean)(New AutoResetEvent(False), True)
        Dim newAddr = uri
        If Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() Then
            Dim uriEndPoint As Uri
            Try
                uriEndPoint = New Uri(newAddr)
            Catch ex As Exception
                Return False
            End Try
            Dim wc As New System.Net.WebClient()
            AddHandler wc.DownloadStringCompleted,
                Sub(sender As Object, eArg As Net.DownloadStringCompletedEventArgs)
                    If eArg.Error IsNot Nothing Then
                        CType(eArg.UserState, Tuple(Of AutoResetEvent, Boolean)).Item2 = False
                    End If
                    CType(eArg.UserState, Tuple(Of AutoResetEvent, Boolean)).Item1.Set()
                End Sub
            wc.DownloadStringAsync(uriEndPoint, state)
            state.Item1.WaitOne()
            Return state.Item2
        Else
            Return System.Uri.TryCreate(newAddr, UriKind.Absolute, Nothing)
        End If
    End Function

End Class